package io.gitee.javalaoniu.mpgen.genarator.util;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;


public class ImageUtils {

    public static void genIco(String firstChar, String savePath) {
        int w = 300;
        int h = 300;

        BufferedImage outerImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D outerGraphics = outerImage.createGraphics();
        outerGraphics.setColor(Color.black);
        outerGraphics.fillOval(0, 0, 300, 300);
        outerGraphics.dispose();

        cutHeadImage(outerImage, savePath, firstChar);
    }

    public static void cutHeadImage(String imagePath, String outPath, String text) {
        // imageUrl = "C:\\Users\\Lenovo\\Pictures\\y9000x.jpg"
        BufferedImage bufferedImage = readImage(imagePath);
        cutHeadImage(bufferedImage, Paths.get(outPath), text);
    }

    public static void cutHeadImage(String imagePath, Path outPath, String text) {
        // imageUrl = "C:\\Users\\Lenovo\\Pictures\\y9000x.jpg"
        BufferedImage bufferedImage = readImage(imagePath);
        cutHeadImage(bufferedImage, outPath, text);
    }

    public static void cutHeadImage(BufferedImage sourceImage, String outPath, String text) {
        cutHeadImage(sourceImage, Paths.get(outPath), text, 3);
    }

    public static void cutHeadImage(BufferedImage sourceImage, Path outPath, String text) {
        cutHeadImage(sourceImage, outPath, text, 3);
    }

    public static void cutHeadImage(BufferedImage sourceImage, Path outPath, String text, int border) {
        BufferedImage avatarImage = null;

        avatarImage = sourceImage;
        int width = avatarImage.getWidth();
        int height = avatarImage.getHeight();

        // 计算图片的左上角点
        int leftTopPointX = 0;
        int leftTopPointY = 0;
        int newWidth = width;
        int newHeight = height;
        if (width > height) {
            leftTopPointX = (width - height) / 2;
            newWidth = height;
        } else {
            leftTopPointY = (height - width) / 2;
            newHeight = width;
        }

        BufferedImage subImage = avatarImage.getSubimage(leftTopPointX, leftTopPointY, newWidth, newHeight);
        BufferedImage subImage32 = changBitDeepTo32(subImage);

        // 透明底的图片 transparent
        BufferedImage transparentImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics = transparentImage.createGraphics();
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 留一个像素的空白区域，这个很重要，画圆的时候把这个覆盖
        int xPixel = 1;
        int yPixel = 1;
        //图片是一个圆型
        Ellipse2D.Double shape = new Ellipse2D.Double(xPixel, yPixel, newWidth - xPixel * 2, newHeight - yPixel * 2);
        //需要保留的区域
        graphics.setClip(shape);
        graphics.drawImage(subImage32.getScaledInstance(newWidth, newHeight, Image.SCALE_DEFAULT), xPixel, yPixel,
                           newWidth - border * 2, newHeight - border * 2, null);
        graphics.dispose();

        //在圆图外面再画一个圆
        //新创建一个graphics，这样画的圆不会有锯齿
        graphics = transparentImage.createGraphics();
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 画白色边框
        Stroke s = new BasicStroke(border * 2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        graphics.setStroke(s);
        graphics.setColor(Color.WHITE);
        graphics.drawOval(border, border, newWidth - border * 2, newHeight - border * 2);
        graphics.dispose();

        writeTextFirst(transparentImage, text);

        saveImage(transparentImage, outPath.toString());
    }

    private static void writeTextFirst(BufferedImage bufferedImage, String text) {
        String firstChar = text.substring(0, 1);
        int centerPointX = bufferedImage.getWidth() / 2;
        int centerPointY = bufferedImage.getHeight() / 2;

        //新创建一个graphics，写字
        Graphics2D graphics = bufferedImage.createGraphics();
        // 消除边缘抗锯齿
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 文本抗锯齿
        graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        graphics.setColor(Color.YELLOW);
        //graphics.setBackground(new Color(0,255,0));
        int fontSize = (int) (Math.min(centerPointX, centerPointY) * 0.9);
        Font font = new Font(graphics.getFont().getName(), Font.BOLD, fontSize);
        graphics.setFont(font);
        FontMetrics fm = graphics.getFontMetrics(font);
        int textHeight = fm.getHeight();
        int textWidth = fm.stringWidth(firstChar);
        graphics.drawString(firstChar, centerPointX - textWidth / 2, centerPointY + textHeight / 4);
        graphics.dispose();
    }

    private static BufferedImage readImage(String imagePath) {
        try {
            File file = new File(imagePath);
            if (!file.exists()) {
                throw new RuntimeException("图片不存在，" + file.getAbsoluteFile());
            }
            return ImageIO.read(file);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static void saveImage(BufferedImage transparentImage, String outPath) {
        try {
            OutputStream os = Files.newOutputStream(Paths.get(outPath));
            ImageIO.write(transparentImage, "png", os);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static BufferedImage changBitDeepTo32(BufferedImage bufferedImage) {
        int width = bufferedImage.getWidth();
        int height = bufferedImage.getHeight();
        BufferedImage newBufferedImage = new BufferedImage(width, height, bufferedImage.getType());
        Graphics2D gr = newBufferedImage.createGraphics();
        //创建、透明背景
        newBufferedImage = gr.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        gr = newBufferedImage.createGraphics();
        //重绘
        gr.drawImage(bufferedImage.getScaledInstance(width, height, Image.SCALE_DEFAULT), 0, 0, width, height, null);
        gr.dispose();
        return newBufferedImage;
    }

    /**
     * 缩小Image，此方法返回源图像按给定宽度、高度限制下缩放后的图像
     *
     * @param inputImage ：压缩后宽度
     *                   ：压缩后高度
     * @throws java.io.IOException return
     */
    public static BufferedImage scaleImage(BufferedImage inputImage, int newWidth, int newHeight) {
        // 获取原始图像透明度类型
        try {
            int type = inputImage.getColorModel().getTransparency();
            int width = inputImage.getWidth();
            int height = inputImage.getHeight();
            // 开启抗锯齿
            RenderingHints renderingHints =
                    new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            // 使用高质量压缩
            renderingHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            BufferedImage img = new BufferedImage(newWidth, newHeight, type);
            Graphics2D graphics2d = img.createGraphics();
            graphics2d.setRenderingHints(renderingHints);
            graphics2d.drawImage(inputImage, 0, 0, newWidth, newHeight, 0, 0, width, height, null);
            graphics2d.dispose();
            return img;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void main(String[] args) throws Exception {

        int w = 300;
        int h = 300;

        BufferedImage outerImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D outerGraphics = outerImage.createGraphics();
        outerGraphics.setColor(Color.black);
        outerGraphics.fillOval(0, 0, 300, 300);
        outerGraphics.dispose();

        cutHeadImage(outerImage, new File("aa.png").toPath(), "M源fadsfasd反对法");


    }
}